/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fr.istia.gesstages.dao;

import java.util.List;
import fr.istia.gesstages.jpa.Apply;
import fr.istia.gesstages.jpa.Offer;
import fr.istia.gesstages.jpa.User;
import fr.istia.gesstages.jpa.UserType;
import fr.istia.gesstages.util.Encryption;
import fr.istia.gesstages.util.Access;
import java.util.Date;
import junit.framework.Assert;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *
 * @author usrlocal
 */
public class InitDB {

    private static IDaoApply daoApply;
    private static IDaoUser daoUser;
    private static IDaoUserType daoUserType;
    private static IDaoOffer daoOffer;
    private static IDaoFile daoFile;
    private static Access access;
    private static Offer stageSopra = new Offer(
            "Mission : vous serez également amené(e) à étudier, puis à actualiser le panorama des principales offres technologiques du marché (Oracle BRM, Ericsson/BSCS, SAP/Highdeal…) en appréciant leur capacité à adresser les enjeux de cette vision prospective",
            "Stage en développement Java EE",
            "Sopra Group",
            "Direction du Recrutement\r\n9 bis rue de Presbourg",
            "75116",
            "Paris",
            new Date("10/11/2011"),
            new Date("16/11/2011"),
            true, true, "Test", "", "EI5", "Laurent", "Amot", "Sébastien Délai", false);
    private static Offer stageCapgemini = new Offer(
            "Etudier et concevoir un système de gestion des offres de stage de l'entreprise",
            "Stage en développement PHP",
            "Capgemini",
            "11 rue de Tilsitt, Place de l'étoile",
            "75017",
            "Paris",
            new Date("20/09/2011"),
            new Date("22/10/2011"),
            true, true, "Test 2", "", "EI5", "Patrick", "Juckolat", "Didier Renaud", true);
    private static Offer stageAtos = new Offer(
            "Dans le cadre de la refonte d’une partie de son SI, le client, une agence leader en location de véhicules, a démarré depuis un an un projet réalisé en méthode Agile Scrum (2 équipes de 7 personnes).",
            "Développement JAVA en équipe Agile H/F",
            "Atos",
            "18 avenue des droits de l'homme",
            "45000",
            "Orléans",
            new Date("11/11/2011"),
            new Date("22/12/2011"),
            true, true, "Test 3", "", "EI5", "Laurent", "Duni", "Jacques Martin", false);
    private static UserType admin = new UserType("Administrateur");
    private static UserType etudiant = new UserType("Etudiant");
    private static UserType invite = new UserType("Invité");

    public InitDB() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
        daoApply = (IDaoApply) ctx.getBean("beanDaoApply");
        daoUser = (IDaoUser) ctx.getBean("beanDaoUser");
        daoUserType = (IDaoUserType) ctx.getBean("beanDaoUserType");
        daoOffer = (IDaoOffer) ctx.getBean("beanDaoOffer");
        daoFile = (IDaoFile) ctx.getBean("beanDaoFile");
        access = (Access) ctx.getBean("beanAccess");
        daoApply.deleteAll();
        daoOffer.deleteAll();
        daoUser.deleteAll();
        daoUserType.deleteAll();
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    @Test
    public void kernelTesting() {
        
        // Types d'utilisateurs
        admin = daoUserType.create(new UserType("Administrateur"));
        etudiant = daoUserType.create(new UserType("Etudiant"));
        invite = daoUserType.create(new UserType("Invité"));
        Assert.assertNotNull(admin);
        Assert.assertNotNull(etudiant);
        Assert.assertNotNull(invite);
        List<UserType> types = daoUserType.findAll();
        Assert.assertEquals(3, types.size());

        // Utilisateurs
        Assert.assertNotNull(daoUser.create(new User(admin, "admin", "21232f297a57a5a743894a0e4a801fc3", "Administrateur", "", "admin@portail-stages.com", false, "")));
        Assert.assertNotNull(daoUser.create(new User(etudiant, "cedric.moreau", "5f4dcc3b5aa765d61d8327deb882cf99", "Moreau", "Cédric", "cem.moreau@gmail.com", true, "EI5")));
        Assert.assertNotNull(daoUser.create(new User(etudiant, "gaetan.loussier", "5f4dcc3b5aa765d61d8327deb882cf99", "LOUSSIER", "Gaëtan", "gaetan.loussier@gmail.com", true, "EI5")));
        Assert.assertNotNull(daoUser.create(new User(etudiant, "hubert.mong", "5f4dcc3b5aa765d61d8327deb882cf99", "Mong", "Hubert", "hubert2000m@gmail.com", false, "EI5")));
        List<User> users = daoUser.findAll();
        User gaetan = daoUser.find("gaetan.loussier");
        User cedric = daoUser.find("cedric.moreau");
        Assert.assertEquals(4, users.size());
        Assert.assertEquals("cedric.moreau", cedric.getLogin());
        Assert.assertEquals("5f4dcc3b5aa765d61d8327deb882cf99", gaetan.getMdp());
        Assert.assertEquals("Gaëtan", gaetan.getPrenom());

        // Offres
        Assert.assertNotNull(daoOffer.create(stageSopra));
        Assert.assertNotNull(daoOffer.create(stageCapgemini));
        Assert.assertEquals(2, daoOffer.findAll().size());
        
        //---------- UTILISATEURS ----------
        User userAdmin = daoUser.find("admin");
        Assert.assertEquals(admin.getId(), userAdmin.getType().getId());
        
        Assert.assertTrue(access.login("cedric.moreau", Encryption.md5("password")));
        Assert.assertFalse(access.login("cedric.moreau", Encryption.md5("fergerg")));
        Assert.assertFalse(access.login("cedric.moreau", "password"));
        List<Offer> offers = daoOffer.findCurrent();
        Assert.assertEquals(1, offers.size());

        //---------- OFFRES ----------
        offers = daoOffer.findArchived("2011");
        Assert.assertEquals(1, offers.size());
        // Archivage
        daoOffer.archiveAll();
        Assert.assertEquals(2, daoOffer.findArchived("2011").size());
        Assert.assertEquals(0, daoOffer.findCurrent().size());
        daoOffer.delete(offers.get(0));
        Assert.assertEquals(1, daoOffer.findArchived("2011").size());
        Assert.assertEquals(0, daoOffer.findCurrent().size());
        Offer offer1 = daoOffer.findArchived("2011").get(0);
        offer1.setArchive(false);
        daoOffer.update(offer1);
        Assert.assertEquals(0, daoOffer.findArchived("2011").size());
        Assert.assertEquals(1, daoOffer.findCurrent().size());

        User user = daoUser.find("cedric.moreau");
        Offer offer = daoOffer.findCurrent().get(0);
        daoApply.create(new Apply(offer, user, 0, new Date()));
        List<Apply> applies = daoApply.findBy(offer);
        Assert.assertEquals(1, applies.size());
        
        /* On crée un deuxième stage non archivée */
        Assert.assertNotNull(daoOffer.create(stageAtos));
        Assert.assertEquals(2, daoOffer.findAll().size());
        /* On recherche les offres non candidatées par l'utilisateur cédric */
        List<Offer> nonCandidateesParCedric = daoOffer.findNotAppliedBy(cedric);
        Assert.assertEquals(1, nonCandidateesParCedric.size());
        
        //---------- UNICITE ----------
        /* On vérifie qu'il y a bien uniquement deux offres */
        offers = daoOffer.findAll();
        Assert.assertEquals(2, offers.size());
        /* Et pas archivées */
        List<Offer> notArchived = daoOffer.findCurrent();
        Assert.assertEquals(2, notArchived.size());
        int nbSuccesses = 2;
        for (Offer o : offers) {
            try {
                daoApply.create(new Apply(o, cedric, 0, new Date()));
            } catch (Exception e) {
                nbSuccesses--;
            }
        }
        /* Sachant qu'il y a 1 offre postulée, on ne devrait avoir réussi qu'une candidature */
        Assert.assertEquals(1, nbSuccesses);
        /* Mais conserver 2 candidatures au total */
        List<Apply> candidaturesDeCedric = daoApply.findBy(cedric);
        Assert.assertEquals(2, candidaturesDeCedric.size());
    }
}
